<template>
  <div class="w-full menu">
    <n-input v-model:value="pattern" placeholder="输入名称搜索">
      <template #suffix>
        <n-icon size="18" class="cursor-pointer">
          <SearchOutlined />
        </n-icon>
      </template>
    </n-input>

    <div class="py-3 menu-list">
      <template v-if="loading">
        <div class="flex items-center justify-center py-4">
          <n-spin size="medium" />
        </div>
      </template>

      <template v-else>
        <n-tree
          ref="treeRef"
          block-line
          :cascade="checkable"
          :checkable="checkable"
          :selectable="!checkable"
          :virtual-scroll="true"
          :pattern="pattern"
          :data="treeData"
          :show-irrelevant-nodes="false"
          :cancelable="false"
          :expand-on-click="false"
          :selected-keys="selectedKeys"
          :expanded-keys="expandedKeys"
          :checked-keys="checkedKeys"
          @update:selected-keys="handleSelectedTree"
          @update:checked-keys="handleCheckedTree"
          @update:expanded-keys="handleOnExpandedKeys"
          :key-field="treeProps.key"
          :label-field="treeProps.label"
          :children-field="treeProps.children"
          :render-suffix="renderSuffix"
        />
      </template>
    </div>
  </div>
</template>

<script lang="ts" setup>
  import { ref, onMounted, h } from 'vue';
  import { SearchOutlined } from '@vicons/antd';
  import { NButton } from 'naive-ui';

  // 定义组件属性
  interface TreeProps {
    key: string;
    label: string;
    children: string;
  }

  interface TreeNode {
    [key: string]: any;
  }

  // 定义组件属性
  const props = withDefaults(
    defineProps<{
      treeData: TreeNode[];
      checkable?: boolean;
      treeProps: TreeProps;
      isAdd?: boolean;
    }>(),
    {
      checkable: false,
      isAdd: false,
      treeData: () => [],
      treeProps: () => ({
        key: 'id',
        label: 'name',
        children: 'child',
      }),
    }
  );

  // 定义事件
  const emit = defineEmits<{
    (e: 'selected-tree', keys: string[]): void;
    (e: 'checked-tree', keys: string[]): void;
    (e: 'on-expanded-keys', keys: string[]): void;
    (e: 'button-add'): void;
  }>();

  // 响应式数据
  const treeRef = ref();
  const loading = ref(true);
  const pattern = ref('');
  const selectedKeys = ref<string[]>([]);
  const expandedKeys = ref<string[]>([]);
  const checkedKeys = ref<string[]>([]);

  // 处理树节点选择
  function handleSelectedTree(keys: string[]) {
    selectedKeys.value = keys;
    emit('selected-tree', selectedKeys.value);
  }

  // 处理树节点勾选
  function handleCheckedTree(keys: string[]) {
    checkedKeys.value = keys;
    emit('checked-tree', checkedKeys.value);
  }

  // 处理展开节点
  function handleOnExpandedKeys(keys: string[]) {
    expandedKeys.value = keys;
    emit('on-expanded-keys', expandedKeys.value);
  }

  // 渲染后缀按钮
  function renderSuffix({ option }: { option: any }) {
    if (props.isAdd !== false && option[props.treeProps.key] === selectedKeys.value[0]) {
      return h(
        NButton,
        {
          text: true,
          type: 'info',
          color: '#409EFF',
          size: 'small',
          round: false,
          onClick: (e: Event) => {
            handleButtonAdd();
            e.stopPropagation();
          },
        },
        {
          default: () => '新增',
        }
      );
    }
    return null;
  }

  // 处理新增按钮点击
  function handleButtonAdd() {
    emit('button-add');
  }

  // 组件挂载完成后
  onMounted(() => {
    loading.value = false;
  });

  // 暴露方法给父组件
  defineExpose({
    treeRef,
    setSelected: (keys: string[]) => {
      selectedKeys.value = keys;
    },
    setExpanded: (keys: string[]) => {
      expandedKeys.value = keys;
    },
    setChecked: (keys: string[]) => {
      checkedKeys.value = keys;
    },
    getCheckedData: () => {
      return treeRef.value?.getCheckedData?.() || { checkedKeys: [], checkedNodes: [] };
    },
    getIndeterminateData: () => {
      return (
        treeRef.value?.getIndeterminateData?.() || { indeterminateKeys: [], indeterminateNodes: [] }
      );
    },
  });
</script>

<style scoped>
  .w-full {
    width: 100%;
  }

  .menu {
    /* 根据需要添加样式 */
  }

  .py-3 {
    padding-top: 0.75rem;
    padding-bottom: 0.75rem;
  }

  .menu-list {
    /* 根据需要添加样式 */
  }

  .flex {
    display: flex;
  }

  .items-center {
    align-items: center;
  }

  .justify-center {
    justify-content: center;
  }

  .py-4 {
    padding-top: 1rem;
    padding-bottom: 1rem;
  }

  .cursor-pointer {
    cursor: pointer;
  }
</style>
